#include "lib/includes.h"
#include "bustcp.h"
//公交通讯相关

//===============================================
U32 MathDesMac( U08 *pbuf, U32 length, U08 checktype )
{
	U32 len ;
	U08 mac[8], mac1[8];
	len = length ;
	if( checktype == 0 )
	{
		CurCalc_DES_MAC64( (SINGLE_DES_ENCRYPTION|ZERO_CBC_IV), COM_desTxKey, 0, pbuf, len ,  mac );
		memcpy( pbuf+len, mac, 8 );
		return 0 ;
	}
	else
	{
		//暂存源校验码
		memcpy( mac1, pbuf+len-8, 8 ) ; 
		CurCalc_DES_MAC64( (SINGLE_DES_ENCRYPTION|ZERO_CBC_IV), COM_desRxKey, 0, pbuf, len-8 ,  mac) ; 
		if ( memcmp( mac, mac1, 8 ) == 0x00 )
		{
			return 0 ;	 	//校验产生的校验码和原校验码相等, 校验成功
		}
		else
		{
			return 1 ;	  	//校验产生的校验码和原校验码不等, 校验失败
		}
	}	
}
/*
**************************************************************************************************************
* 通讯发送数据报文格式组合
* comm:报文标识
* buf:数据缓冲区
* bufsize:数据体长度
**************************************************************************************************************
*/
U32 ComData_HeadTx( U16 comm, U08 *buf, U32 *bufsize )
{
	//长度
	buf[0] = ( ( bufsize[0] + 8 ) >> 8 ) & 0x00FF;
	buf[1] = ( bufsize[0] + 8 ) & 0x00FF;
	//协议版本
	buf[2] = 0x20;
	buf[3] = 0x00;
	//报文标识
	buf[4] = ( comm >> 8 ) & 0x00FF;
	buf[5] = comm & 0x00FF;
	
	buf[6] = ( COM_SerialNum >> 8 );
	buf[7] = COM_SerialNum;
	
	MathDesMac( buf, bufsize[0], 0 );
	
	(*bufsize) += 8;
	return 0;
}
/*
**************************************************************************************************************
* 通讯接收到数据报文格式解析
* comm:报文标识
* buf:数据缓冲区
* bufsize:数据总长度
**************************************************************************************************************
*/
U32 ComData_HeadRx( U16 comm, U08 *buf, U32 bufsize )
{
	U32 m;
	
	//报文长度
	m = ( buf[0] << 8) |
		( buf[1] << 0);
	if( m > bufsize )
	{ DEF_SysCom_Debug; return 10; }
	bufsize = m;
	//报文序号
	if( COM_SerialNum != ( ( buf[6] << 8 ) | buf[7] ) )
	{ DEF_SysCom_Debug; return 20; }
	//MAC校验
	if( MathDesMac( buf, bufsize, 1 ) != 0 )		
	{ DEF_SysCom_Debug; return 30; }
	//POS编号对比
	if( memcmp( &buf[8], gSamAppInfo.PsamTID, 6 ) !=0 )
	{ DEF_SysCom_Debug; return 40; }
	//命令头	
	m = ( ( buf[4] << 8 ) | buf[5] );
	if( m == 0xFFFF )
	{
		//错误报文序号
		//错误代码
		printf("ID:%02X%02X Ee:%02X%02X\r\n", buf[14],buf[15],buf[16],buf[17] );
		DEF_SysCom_Debug; 
		return 100;
	}
	else if( m != comm )
	{ DEF_SysCom_Debug; return 50; }
	return 0; 
}
/*
**************************************************************************************************************
*会话请求组帧
**************************************************************************************************************
*/
U32 AH_Comm_Tx_Session( U08 *buf, U32 *bufsize )
{
	U32 len,k;

	len = 8;
	//========>>数据
	//Pos编号
	memcpy(&buf[len], gSamAppInfo.PsamTID, 6);
	len +=6;
	//终端随机数
	srand( SYS_RTC_Time.Second );
	k = rand();
	
	buf[len++] = SYS_RTC_Time.Second + 21;
	buf[len++] = ~SYS_RTC_Time.Second;
	buf[len++] = SYS_RTC_Time.Second + 0x5A;
	buf[len++] = SYS_RTC_Time.Second + 0x39;
	buf[len++] = ( k >> 24 );
	buf[len++] = ( k >> 16 );
	buf[len++] = ( k >>  8 );
	buf[len++] = ( k >>  0 );

	//PSAM卡卡号
	memcpy( &buf[len], gSamAppInfo.PsamTID, 6 );
	len +=6;
	//终端类型
	buf[len++] = 0x00;
	buf[len++] = 0x00;
	//终端时间
	buf[len++] = SYS_RTC_Time.Year_H;
	buf[len++] = SYS_RTC_Time.Year_L;
	buf[len++] = SYS_RTC_Time.Month;
	buf[len++] = SYS_RTC_Time.Day;
	buf[len++] = SYS_RTC_Time.Hour;
	buf[len++] = SYS_RTC_Time.Minute;
	buf[len++] = SYS_RTC_Time.Second;

	ComData_HeadTx( 0x0001, buf, &len );
	*bufsize = len;

	return 0;
}

U32 Com_Bus_TcpSession( void )
{
//	U08 buf[8];
	U32 rcode, i;
	RTC_CLOCK	rtc_time;
	U08 timebuf[8];
	time_t rawtime;
    struct tm* timeinfo;
    char buffer[30];
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    //printf( "It is now: %s", ctime( &time_of_day ) );
    strftime(buffer,sizeof(buffer),"%Y%m%d%H%M%S",timeinfo);
    CurCalc_ASCII_Proc( 2, (U08*)buffer, strlen(buffer),timebuf, 0 );
	Hook_Debug_TxData("->会话请求中...");

	SYS_RTC_Time.Year_H = timebuf[0];
	SYS_RTC_Time.Year_L = timebuf[1];
	SYS_RTC_Time.Month  = timebuf[2];
	SYS_RTC_Time.Day    = timebuf[3];
	SYS_RTC_Time.Hour   = timebuf[4];
	SYS_RTC_Time.Minute = timebuf[5];
	SYS_RTC_Time.Second = timebuf[6];
	//密钥选择
	if( OthCfg.ComKeyStat == 1 )
	{
		memcpy( COM_desTxKey, &OthCfg.ComKey[0], 8 );
		memcpy( COM_desRxKey, &OthCfg.ComKey[0], 8 );
	}
	else
	{
		COM_desTxKey[0] = 0;
		COM_desTxKey[1] = 0;
		memcpy( COM_desTxKey + 2, gSamAppInfo.PsamTID, 6 );
		COM_desRxKey[0] = 0;
		COM_desRxKey[1] = 0;
		memcpy( COM_desRxKey + 2, gSamAppInfo.PsamTID, 6 );
	}

	//请求命令
	COM_SerialNum++;

	for( i = 0; i < DEF_SendRecErrMaxNumber; i++ )
	{
		if( AH_Comm_Tx_Session( COM_TxRxBuf, &COM_TxRxBufSize ) != 0 )		//会话请求组帧
		{ return 1; }	
		
		//发送命令
		rcode = Com_Dev_TxData( COM_TxRxBuf, COM_TxRxBufSize, ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum ); 
		if( rcode != 0 )
		{ DEF_SysCom_Debug; return rcode; }
		//接收命令
		rcode = Com_Dev_RxData( COM_TxRxBuf, &COM_TxRxBufSize, sizeof(COM_TxRxBuf), ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum ); 
		if( rcode != 0 )
		{ DEF_SysCom_Debug; return rcode; }

		//==============>>接收数据解析
		rcode = ComData_HeadRx( 0x8001, COM_TxRxBuf, COM_TxRxBufSize );
		if( rcode == 100 )
		{ return rcode; }
		else if( rcode != 0 )
		{ return rcode; }

		//<2> 有效数据处理
		//<2.1> 系统时间更新													 						                 			
		rtc_time.Year_H = COM_TxRxBuf[14];
		rtc_time.Year_L = COM_TxRxBuf[15];
		rtc_time.Month  = COM_TxRxBuf[16];
		rtc_time.Day    = COM_TxRxBuf[17];
		rtc_time.Hour   = COM_TxRxBuf[18];
		rtc_time.Minute = COM_TxRxBuf[19];	
		rtc_time.Second = COM_TxRxBuf[20];	
		rtc_time.Week	= 0;

		RTC_WriteSysTime( &rtc_time );         			//保存系统时间 
		RTC_ReadSysTime( &SYS_RTC_Time );				//重新获取系统时间

		//<2.2>密钥更新
		if( COM_TxRxBuf[22] == 1 )						//1.交换主密钥
		{
			//解密密钥
			CurCalc_DES_DesOperation(	&COM_TxRxBuf[23], 
										(unsigned char *)0x00, 
										COM_desRxKey, 
										SINGLE_DES_DECRYPTION | ZERO_CBC_IV, 
										1 ) ;
			memcpy( &OthCfg.ComKey[0], &COM_TxRxBuf[23], 8);
			OthCfg.ComKeyStat = 1;
			APP_Save_CfgOth( 0 );						//保存参数zj20100912

			APP_Save_OthCfg( 0 );	
			return 0x12345678;
		}
		else if( COM_TxRxBuf[22] == 2 )					//2.交换临时验证密钥与临时加密密钥
		{
			//解密密钥
			CurCalc_DES_DesOperation( 	&COM_TxRxBuf[31], 
										(unsigned char *)0x00, 
										COM_desRxKey, 
										SINGLE_DES_DECRYPTION | ZERO_CBC_IV, 
										1 ) ;
			memcpy( COM_desRxKey, &COM_TxRxBuf[31], 8 );
			memcpy( COM_desTxKey, &COM_TxRxBuf[31], 8 );
			return 0;
		}
		else if( COM_TxRxBuf[22] == 0 )
		{ return 0; }
	}
	//DEF_SysCom_Debug; 
	return 1;
}


/*
**************************************************************************************************************
*消费记录组帧	  (消费记录与锁卡记录) 1区
**************************************************************************************************************
*/
U32 AH_Comm_Tx_SubRec( U08 *buf, U32 *bufsize )
{
	U32 RecCout,i,rcode,stat;
	U32 len;
	U08 bufback[4];
	
	CurCalc_DataSet( bufback, 0, 4 );
	rcode = APP_Get_RecFileNum( DEF_RecMoryBank_Black01, 1, &stat ); 
	if( rcode != 0 )						    		//消费记录
	{ DEF_SysCom_Debug; return 1; }
	if( stat == 0 )										//终端无消费记录
	{ return 1; }

	RecCout = 0;

	len = 8;
	//========>>数据
	//Pos编号
	memcpy( &buf[len], gSamAppInfo.PsamTID, 6 );
	len +=6;
	
	for( i = 0; i < stat; i++ )							//组一包数据
	{
		bufback[0] = buf[len-4];
		bufback[1] = buf[len-3];
		bufback[2] = buf[len-2];
		bufback[3] = buf[len-1];

		if( RecCout > 0 )
		{ break; }
		rcode = APP_Read_RecFile_NotServer( DEF_RecMoryBank_Black01, 1, i+1, &buf[len-4] );
	
		buf[len-4] = bufback[0];
		buf[len-3] = bufback[1];
		buf[len-2] = bufback[2];
		buf[len-1] = bufback[3];		
		
		if( rcode != 0 )
		{
			if( rcode == NC_NoRecERR )
			{ break; }
			if( rcode == NC_FlashErr )
			{ DEF_SysCom_Debug; return rcode; }
			else
			{ continue; }
		}

		switch (buf[len])
		{
			case DEF_RecType_QD:		//签点记录
				len += 36;
				break;
			case DEF_RecType_MotoKQ:	//考勤记录
				len += 33;
				break;
			case DEF_RecType_CircChe:	//线路变更记录
				len += 34;
				break;
			case DEF_RecType_Clr:		//清0记录
			case DEF_RecType_Trade:		//消费记录
				len += 75;
				break;
			case DEF_RecType_MotoZW:	//司机当班总额记录
				len += 55;
				break;
			case DEF_RecType_Blacklist:	//安全黑名单
				len += 26;
				break;
			default:					//(错误记录)
				DEF_SysCom_Debug;
				continue;
		}
		RecCout++;
	}

	COM_rcdSendNum = i;

	ComData_HeadTx( 0x0201, buf, &len );
	*bufsize = len;

	return 0;
}

/*
**************************************************************************************************************
*
* 函数原型：U32 Com_Bus_TcpRecSend( void )
*
* 函数功能：上传记录
*			标准公交Tcp通讯应用层处理				 
*
* 函数输入：无
*                
* 函数输出：无
*
* 函数返回：无 
*   
**************************************************************************************************************
*/
U32 Com_Bus_TcpRecSend( void )
{
	U32 rcode, i;

	while( 1 )
	{
		//记录命令
		COM_SerialNum++;
		Hook_Debug_TxData("->记录上传中...");
		for( i = 0; i < DEF_SendRecErrMaxNumber; i++ )					//如果发送失败，可以重复发送
		{
			if( AH_Comm_Tx_SubRec( COM_TxRxBuf, &COM_TxRxBufSize ) != 0 )//获取消费记录
			{ Hook_Debug_TxData("->无记录!");return 1; }		
			//发送命令
			rcode = Com_Dev_TxData( COM_TxRxBuf, COM_TxRxBufSize, ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum );
			if( rcode != 0 )
			{ DEF_SysCom_Debug; return rcode; }
			//接收命令
			rcode = Com_Dev_RxData( COM_TxRxBuf, &COM_TxRxBufSize, sizeof(COM_TxRxBuf), ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum );
			if( rcode != 0 )
			{ Hook_Debug_TxData("->无应答!");DEF_SysCom_Debug; return rcode; }

			//==============>>接收数据解析
			rcode = ComData_HeadRx( 0x8201, COM_TxRxBuf, COM_TxRxBufSize );
			if( rcode == 100 )
			{ Hook_Debug_TxData("<-上传失败");DEF_SysCom_Debug;return rcode; }
			else if( rcode != 0 )
			{ Hook_Debug_TxData("<-上传失败");DEF_SysCom_Debug;return rcode; }
	
			//删除记录
			APP_Delete_RecFile( DEF_RecMoryBank_Black01, 1, COM_TxRxBuf, COM_rcdSendNum );	
			if( rcode != 0 )
			{ DEF_SysCom_Debug; return 2; }
			Hook_Debug_TxData("<-上传成功");								
			break;														//发送成功	
		}
		if( i >= DEF_SendRecErrMaxNumber )								//发送失败
		{ Hook_Debug_TxData("<-上传失败");return 1; }	
	}
}


/*
**************************************************************************************************************
* 6.6.2	线路票价
**************************************************************************************************************
*/
U32 AH_Comm_Tx_PriceParaUp( U08 *buf, U32 *bufsize )
{
	U32 len;

	len = 8;
	//========>>数据
	//<1>POS编号
	memcpy( &buf[len], gSamAppInfo.PsamTID, 6 );
	len +=6;
	//<2> 线路编号
	memcpy( &buf[len], DealCfg.CircuitryID, 2 );	
	len +=2;
	//<3> 版本号
	buf[len++] = ( DealCfg.Ver >> 8 ) & 0xff;
	buf[len++] =   DealCfg.Ver & 0xff;
 
	ComData_HeadTx( 0x0101, buf, &len );
	*bufsize = len;
 
 	return 0;
} 
U32 AH_Comm_Rx_PriceParaUp( U08 *buf )
{
	U32 len,i;
	U08 cirID[4];
					 
	len =0;
    //<1> POS编号
	if( memcmp( gSamAppInfo.PsamTID, &buf[len], 6 ) != 0 )
	{ 
		DEF_SysCom_Debug; 
		return 1; 
	}	
	len +=6;
	//<2> 线路编号
	cirID[3] = 0;
	if( memcmp( DealCfg.CircuitryID, &buf[len], 2 ) != 0 )
	{ 
		memcpy( cirID, DealCfg.CircuitryID, 2 ); 
		cirID[3] = 1;						//暂存老的线路标识，因为需要保存线路变更记录
	}
	memcpy( DealCfg.CircuitryID, &buf[len], 2 );	
	printf("DealCfg.CircuitryID  = %02x%02x\r\n", DealCfg.CircuitryID[0],DealCfg.CircuitryID[1] );
	len +=2;
	//<3> 版本号
//	DealCfg.Ver = (buf[len++]<<8);
//	DealCfg.Ver = DealCfg.Ver | buf[len++];
	len +=2;
	//<4> 版本时间
	memcpy(DealCfg.Time, &buf[len], 7);
	len +=7;

	//<5> GPS状态
	DealCfg.GPSStat = buf[len++];
	//<6> GPS上传时间间隔
	DealCfg.GPSContTime = buf[len++];
	//<7> 终端长连接/短连接
	DealCfg.GPSLinkStat = buf[len++];

	//<8> 票价计算模式
	DealCfg.TimePriceStat = buf[len++];
	//<9> 逃票票价
	DealCfg.FaultUnitPrice  = (buf[len++]<<8);
	DealCfg.FaultUnitPrice |= buf[len++];
	
	//<10> 票价
	DealCfg.UnitPrice  = (buf[len++]<<8);
	DealCfg.UnitPrice |= buf[len++];
	printf("DealCfg.UnitPrice  = %d\r\n", DealCfg.UnitPrice );
	//<11> 2个时段季节高峰票价
	for( i = 0; i < 2; i++ )
	{
		//票价
		DealCfg.BusyPrice3M[i].UnitPrice  = (buf[len++]<<8);
		DealCfg.BusyPrice3M[i].UnitPrice |= buf[len++];
		//开始时间
		DealCfg.BusyPrice3M[i].StaMMDD  = (buf[len++]<<8);
		DealCfg.BusyPrice3M[i].StaMMDD |= buf[len++];
		//结束时间
		DealCfg.BusyPrice3M[i].EndMMDD  = (buf[len++]<<8);
		DealCfg.BusyPrice3M[i].EndMMDD |= buf[len++];
	}
	//<12> 3个时间高峰票价
	for( i = 0; i < 3; i++ )
	{
		//票价
		DealCfg.BusyPrice[i].UnitPrice  = (buf[len++]<<8);
		DealCfg.BusyPrice[i].UnitPrice |= buf[len++];
		//开始时间
		DealCfg.BusyPrice[i].StaHHMM  = (buf[len++]<<8);
		DealCfg.BusyPrice[i].StaHHMM |=  buf[len++];
		//结束时间
		DealCfg.BusyPrice[i].EndHHMM  = (buf[len++]<<8);
		DealCfg.BusyPrice[i].EndHHMM |= buf[len++];
	}

	//<13> 票价卡类别数量
	DealCfg.CardTypeCout = buf[len++];

	if( DealCfg.CardTypeCout > 25 )
	{ DealCfg.CardTypeCout =25; }

	//<14> 票价信息
	for( i = 0; i < DealCfg.CardTypeCout; i++ )
	{
		//卡类别代码
		DealCfg.DiscInfo[i].CardType = buf[len++];
		//启用标识	 钱包状态  月票状态	 次卡状态  是否判断黑名单
		DealCfg.DiscInfo[i].CardStat = ( buf[len++] << 8 ); 
		DealCfg.DiscInfo[i].CardStat |= buf[len++];
		//连刷状态
		DealCfg.DiscInfo[i].TimeCout = buf[len++];
		//钱包折扣
		DealCfg.DiscInfo[i].PurseDisc = buf[len++];
		//月票折扣
		DealCfg.DiscInfo[i].MonthDisc = buf[len++];
		//语音提示内容
		memcpy( DealCfg.DiscInfo[i].AudioBuf, &buf[len], 10 );
	    len +=10;
		//显示提示内容
		memcpy( DealCfg.DiscInfo[i].DisBuf, &buf[len], 10 );
	    len +=10;

	    printf("DealCfg.DiscInfo[%d].CardType  = %d\r\n", i,DealCfg.DiscInfo[i].CardType );
	    printf("DealCfg.DiscInfo[%d].CardStat  = %d\r\n", i,DealCfg.DiscInfo[i].CardStat );
	    printf("DealCfg.DiscInfo[%d].PurseDisc = %d\r\n", i,DealCfg.DiscInfo[i].PurseDisc );
	    printf("DealCfg.DiscInfo[%d].AudioBuf  = %s\r\n", i,DealCfg.DiscInfo[i].AudioBuf );
	    printf("DealCfg.DiscInfo[%d].DisBuf    = %s\r\n", i,DealCfg.DiscInfo[i].DisBuf );
	}

	APP_Save_DealCfg( 0 );					//保存参数
	//APP_ComCheck();									//长短连接检测

	if( cirID[3] != 0 )
	{
		TradeInformation.DealTime[0] = SYS_RTC_Time.Year_H;
		TradeInformation.DealTime[1] = SYS_RTC_Time.Year_L;
		TradeInformation.DealTime[2] = SYS_RTC_Time.Month;
		TradeInformation.DealTime[3] = SYS_RTC_Time.Day;
		TradeInformation.DealTime[4] = SYS_RTC_Time.Hour;
		TradeInformation.DealTime[5] = SYS_RTC_Time.Minute;
		TradeInformation.DealTime[6] = SYS_RTC_Time.Second;			//暂存当前系统时钟	 

		//memset( M1_Publish.CityID, 0, 8 );  					//卡应用序列号 线路卡卡号
	
		//M1_Publish.HolderCardSn = 0;							//持卡序号
		
		//APP_WriteRec_Circ( DEF_RecMoryBank_Black01, cirID );
											//保存线路变更记录		
	}
	
	return 0;
}

/*
**************************************************************************************************************
*
* 函数原型：U32 Com_Bus_TcpPriceParaUD( void )
*
* 函数功能：6.6.2	线路票价
*			标准公交Tcp通讯应用层处理				 
*
* 函数输入：无
*                
* 函数输出：无
*
* 函数返回：无 
*   
**************************************************************************************************************
*/
U32 Com_Bus_TcpPriceParaUD( void )
{
	U32 i, rcode;

	//请求命令
	COM_SerialNum++;
	Hook_Debug_TxData("->票价下发中...");
	
	for( i = 0; i < DEF_SendRecErrMaxNumber; i++ )
	{
		if( AH_Comm_Tx_PriceParaUp( COM_TxRxBuf, &COM_TxRxBufSize ) != 0 )	
		{ return 1; }
	
		//发送命令
		rcode = Com_Dev_TxData( COM_TxRxBuf, COM_TxRxBufSize, ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum );
		if( rcode != 0 )
		{ DEF_SysCom_Debug; return rcode; }
		//接收命令
		rcode = Com_Dev_RxData( COM_TxRxBuf, &COM_TxRxBufSize, sizeof(COM_TxRxBuf), ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum );
		if( rcode != 0 )
		{ Hook_Debug_TxData("<-无应答!");DEF_SysCom_Debug; return rcode; }
	
		//==============>>接收数据解析
		rcode = ComData_HeadRx( 0x8101, COM_TxRxBuf, COM_TxRxBufSize );
		if( rcode == 100 )
		{ DEF_SysCom_Debug;return rcode; }
		else if( rcode != 0 )
		{ DEF_SysCom_Debug;return rcode; }
		Hook_Debug_TxData("<-下发成功!");	
		//线路票价更新处理
		return ( AH_Comm_Rx_PriceParaUp( &COM_TxRxBuf[8] ) );
	}
	return 1;	
}

/*
**************************************************************************************************************
* 终端信息
**************************************************************************************************************
*/
// U32 APP_ReadBlacklistVersion( U32 ID, U32 *BlacklistVersion )					//获取黑名单版本
// {
// 	*BlacklistVersion = 0;
// 	return 0;
// }

// U32 APP_ReadBlacklistNumber( U32 ID, U32 *BlacklistNumber )//获取黑名单数量
// {
// 	*BlacklistNumber = 0;
// 	return 0;
// }


U32 Data_ASCII_Check( U08 *data, U32 len )
{
	U32 i,k;
	
	k= 0;
	for( i = 0; i < len; i++ )
	{
		if( ( data[i] < '0' ) || ( data[i] > '9' ) )
		{ data[i] = 0; k++; }
		else if( k != 0 )
		{ data[i] = 0; }
	}
	return k;
}
U32 AH_Comm_Tx_Terminus( U08 *buf, U32 *bufsize )
{
	U08 verbuf[16]={0};
	U32 len;
	U32 res,rcode;
	U32 recnum; 

	len = 8;
	//========>>数据
	//<1>POS编号
	memcpy( &buf[len], gSamAppInfo.PsamTID, 6 );
	len +=6;
	//<2>线路编号
	memcpy( &buf[len], DealCfg.CircuitryID, 2 );
	len +=2;
	//<3>通讯类型
	buf[len++] = SysCfg.ComType;
	//<4>硬件版本号
	buf[len++] = 0x00;
	buf[len++] = 0x12;

	//<5>嵌入式软件版本
	memset( verbuf, 0, 16 );
	memcpy( verbuf, POS_SoftVer, strlen( POS_SoftVer ) );
	memcpy( &buf[len], verbuf, 16 );
	len +=16;
	//<6>未采记录个数
	res = APP_Get_RecFileNum( DEF_RecMoryBank_Black01, 1, &recnum );
	if( res != 0 )
	{ DEF_SysCom_Debug; return 1; }
	buf[len++] = (recnum >> 24) & 0xff;
	buf[len++] = (recnum >> 16) & 0xff;
	buf[len++] = (recnum >>  8) & 0xff;
	buf[len++] = (recnum >>  0) & 0xff;
	//<7>增量黑名单版本号
	res = APP_ReadBlacklistVersion(DEF_BlkMoryBank_Black01, &recnum);
	if( res != 0 )
	{ DEF_SysCom_Debug; return 1; }
	buf[len++] = (recnum >> 24) & 0xff;
	buf[len++] = (recnum >> 16) & 0xff;
	buf[len++] = (recnum >>  8) & 0xff;
	buf[len++] = (recnum >>  0) & 0xff;
	//<8>增量黑名单个数
	res = APP_ReadBlacklistNumber(DEF_BlkMoryBank_Black01, &recnum);
	if( res != 0 )
	{ DEF_SysCom_Debug; return 1; }
	buf[len++] = (recnum >> 24) & 0xff;
	buf[len++] = (recnum >> 16) & 0xff;
	buf[len++] = (recnum >>  8) & 0xff;
	buf[len++] = (recnum >>  0) & 0xff;
    //<9> GPS状态
	buf[len++] = DealCfg.GPSStat;
	//<10> 当前经度
	memcpy( &buf[len], gGPS_CurLongitude, 5 );
	len +=5;
	//<11> 当前维度
	memcpy( &buf[len], gGPS_CurLatitude, 5 );
	len +=5;
	//<12> GPS版本号
	buf[len++] = GpsInfo.Ver[0];
	buf[len++] = GpsInfo.Ver[1];
	buf[len++] = GpsInfo.Ver[2];
	buf[len++] = GpsInfo.Ver[3];
	//<11> 站点间票价版本号
	buf[len++] = GpsUnPr.Ver[0];
	buf[len++] = GpsUnPr.Ver[1];
	buf[len++] = GpsUnPr.Ver[2];
	buf[len++] = GpsUnPr.Ver[3];
	//<12> 参数卡版本
	buf[len++] = (SysCfg.Ver >> 8)&0xff;
	buf[len++] =  SysCfg.Ver & 0xff;
	//<13> 线路票价卡版本
	buf[len++] = (DealCfg.Ver >>8)&0xff;
	buf[len++] =  DealCfg.Ver &0xff;
	//<14> 互联互通版本号
	memcpy( &buf[len], CityIDCfg.Ver, 4 );
	len += 4;
	//<15> 终端时间
	buf[len++] = SYS_RTC_Time.Year_H;
	buf[len++] = SYS_RTC_Time.Year_L;
	buf[len++] = SYS_RTC_Time.Month;
	buf[len++] = SYS_RTC_Time.Day;
	buf[len++] = SYS_RTC_Time.Hour;
	buf[len++] = SYS_RTC_Time.Minute;
	buf[len++] = SYS_RTC_Time.Second;
 
	//<16>终端编号				银联使用
	rcode = UP_Read_PosNum( &buf[len] );
	if( rcode != 0 )
	{
		DEF_SysCom_Debug;
		return 1;
	}
	Data_ASCII_Check( &buf[len], 8 );
	len += 8;
	//<17>商户编号				银联使用
	rcode = UP_Read_ManageNum( &buf[len] );
	if( rcode != 0 )
	{
		DEF_SysCom_Debug;
		return 1;
	}
	Data_ASCII_Check( &buf[len], 15 );
	len += 15;

	//<18>银联认证中心公钥参数	银联使用
	rcode = UP_Read_Ver( UP_CAKEY_INDEX, &res );
	if( rcode != 0 )
	{
		DEF_SysCom_Debug;
		return 1;
	}
	buf[len]   = ( res >> 8 );
	buf[len+1] =   res;
	len += 2;
	//<19>银联IC 卡其他参数		银联使用
	rcode = UP_Read_Ver( UP_ICPAR_INDEX, &res );
	if( rcode != 0 )
	{
		DEF_SysCom_Debug;
		return 1;
	}	
	buf[len]   = ( res >> 8 );
	buf[len+1] =   res;
	len += 2;
	//<20>银联密钥失效日期		银联使用
	memcpy( &buf[len], "\x00\x00\x00\x00", 4 );
	len += 4;
	//<21>语音包版本	
	res = 0;
	buf[len++] = ( res >> 8 ) & 0xFF;
	buf[len++] = res & 0xFF;
	//<22>语言包版本
	buf[len++] = 0;
	buf[len++] = 0;
	//<23> 银行卡bin号版本号
	memcpy( &buf[len], &UPBinInfo.Ver[2], 2 );
	len += 2;
 
	ComData_HeadTx( 0x0003, buf, &len );
	*bufsize = len;
 
 	return 0;
} 

/*
**************************************************************************************************************
*
* 函数原型：U32 Com_Bus_TcpTerminus( void )
*
* 函数功能：上传终端信息
*			标准公交Tcp通讯应用层处理				 
*
* 函数输入：无
*                
* 函数输出：无
*
* 函数返回：无 
*   
**************************************************************************************************************
*/
U32 Com_Bus_TcpTerminus( void )
{
	U32 rcode, i;
	U08 buf[16];
//	RTC_CLOCK	rtc_time;

	//请求命令
	COM_SerialNum++;
	Hook_Debug_TxData("->终端信息上传...");
	for( i = 0; i < DEF_SendRecErrMaxNumber; i++ )
	{
		if( AH_Comm_Tx_Terminus( COM_TxRxBuf, &COM_TxRxBufSize ) != 0 )	
		{ return 1; }
	
		//发送命令
		rcode = Com_Dev_TxData( COM_TxRxBuf, COM_TxRxBufSize, ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum ); 
		if( rcode != 0 )
		{ DEF_SysCom_Debug; return rcode; }
		//接收命令
		rcode = Com_Dev_RxData( COM_TxRxBuf, &COM_TxRxBufSize, sizeof(COM_TxRxBuf), ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum ); 
		if( rcode != 0 )
		{ DEF_SysCom_Debug; return rcode; }
	
		//==============>>接收数据解析
		rcode = ComData_HeadRx( 0x8003, COM_TxRxBuf, COM_TxRxBufSize );
		if( rcode == 100 )
		{ DEF_SysCom_Debug;return rcode; }
		else if( rcode != 0 )
		{ DEF_SysCom_Debug;return rcode; }
	
		//<2> 有效数据处理
		//<2.1> 系统时间更新
// 		rtc_time.Year_H = COM_TxRxBuf[14];
// 		rtc_time.Year_L = COM_TxRxBuf[15];
// 		rtc_time.Month  = COM_TxRxBuf[16];
// 		rtc_time.Day    = COM_TxRxBuf[17];
// 		rtc_time.Hour   = COM_TxRxBuf[18];
// 		rtc_time.Minute = COM_TxRxBuf[19];	
// 		rtc_time.Second = COM_TxRxBuf[20];	
// 		rtc_time.Week	= 0;

// 		RTC_WriteSysTime( &rtc_time );         		//保存系统时间 
// 		RTC_ReadSysTime( &SYS_RTC_Time );			//重新获取系统时间
		//<2.2> 更新标记
		COM_ParUpdate = (COM_TxRxBuf[21]<<8)|COM_TxRxBuf[22];
		
		rcode = (COM_TxRxBuf[23]<<8)|COM_TxRxBuf[24];
		if(( SysCfg.CarCode != rcode )||( SysCfg.BillTimeOut != COM_TxRxBuf[48] )||( SysCfg.GpsTimeCont != COM_TxRxBuf[49] ))
		{
			SysCfg.CarCode = rcode;					//车辆编号保存
			SysCfg.BillTimeOut = COM_TxRxBuf[48];	//分段收费上下车超时时间
			SysCfg.GpsTimeCont = COM_TxRxBuf[49];	//GPS上传间隔时间
			APP_Save_SysCfg( 0 );	
		}
		
		//终端编号				银联使用
		rcode = UP_Read_PosNum( buf );
		if( rcode != 0 )
		{
			DEF_SysCom_Debug;
			return 1;
		}
		if( memcmp( buf, &COM_TxRxBuf[25], 8 ) != 0 )
		{											//银联的终端编号不一样，需要保存
			goto SAVE;
		}
		//商户编号				银联使用
		rcode = UP_Read_ManageNum( buf );
		if( rcode != 0 )
		{
			DEF_SysCom_Debug;
			return 1;
		}
		if( memcmp( buf, &COM_TxRxBuf[25+8], 15 ) != 0 )
		{											//银联的商户编号不一样，需要保存
			SAVE:
			Data_ASCII_Check( &COM_TxRxBuf[25], 8 );
			rcode = UP_Write_PosNum( &COM_TxRxBuf[25] ); 
			if( rcode != 0 )
			{
				DEF_SysCom_Debug;
				return 1;
			}
			Data_ASCII_Check( &COM_TxRxBuf[25+8], 15 );
			rcode = UP_Write_ManageNum( &COM_TxRxBuf[25+8] ); 
			if( rcode != 0 )
			{
				DEF_SysCom_Debug;
				return 1;
			}
		}
		Hook_Debug_TxData("<-信息上传成功!");
		printf("COM_ParUpdate   = %d\r\n", COM_ParUpdate);
		//printf("UP_PosNum       = %s\r\n", (char*)UP_PosNum);
		//printf("UP_ManageNum    = %s\r\n", (char*)UP_ManageNum);

		return 0;
	}
	return 1;		
}

/*
**************************************************************************************************************
* 
**************************************************************************************************************
*/
U32 AH_Comm_Tx_TcpUP_CA( U08 *buf, U32 *bufsize, U08 *vcn )
{
	U32 len;

	len = 8;
	//========>>数据
	//<1>POS编号
	CurCalc_DataCpy( &buf[len], gSamAppInfo.PsamTID, 6 );
	len +=6;
	//<2>版本号 第一次为终端当前版本号
	memcpy( &buf[len], &vcn[0], 2 );
	len += 2;
	
	//总组数 第一次为0
	memcpy( &buf[len], &vcn[2], 2 );
	len += 2;
	
	//要下发组号 第一次为0
	memcpy( &buf[len], &vcn[4], 2 );
	len += 2;

	ComData_HeadTx( 0x0105, buf, &len );
	*bufsize = len;
 
 	return 0;
}

U32 AH_Comm_Rx_TcpUP_CA( U08 *buf, U32 bufsize, U08 *vcn )
{
	U32 len,cout,rcode,ver;
	U08 rev_buf[400];
	U32 recnum;

	len =0;
	if( bufsize <= 12 )
	{
		DEF_SysCom_Debug; 
		return 1; 
	}	
    //<1> POS编号
	if( memcmp( gSamAppInfo.PsamTID, &buf[len], 6 ) != 0 )
	{
		DEF_SysCom_Debug; 
		return 1; 
	}
	len +=6;	
	//<2> 版本号,总组数，当前组号

	if( memcmp( &vcn[2], "\x00\x00\x00\x00", 4 ) == 0 )
	{											//第一次请求 总组数，当前组号都为0
		if( memcmp( &vcn[0], &buf[len], 2 ) == 0 )
		{										//第一次请的版本号与响应的版本号一样，有可能不需要下载
			return 1;							//不需要下载
		}
		else									//第一次请的版本号与响应的版本号不一样，进行下载
		{
			if( APP_Get_RecFileNum( DEF_RecMoryBank_Black06, 1, &recnum ) == 0 )
			{												 	//获取未上传的记录
				if(recnum)
				{
					if(APP_Delete_RecFile( DEF_RecMoryBank_Black06, 1, rev_buf, recnum ))
					{
						return 1;
					} 	
				}														
			}
			rcode = UP_Write_CAKeyOrICParStat( UP_CAKEY_INDEX, 1 );
			if( rcode != 0 )					//更新状态
			{ return 1; }

			memcpy( vcn, &buf[len], 6 );		//更新当前的版本，总数，组号
//			cout = ( ( vcn[4] << 8 ) | vcn[5] );
//			cout++;
//			vcn[4] = cout >> 8;
//			vcn[5] = cout;
			
			len += 6;
			bufsize -= 12;

			rcode = UP_CAKeyTLV_AnalysisCheckAndSave( &buf[len], bufsize );
			if( rcode != 0 )					//保存参数
			{
				DEF_SysCom_Debug;
				APP_SysErrProc();
				return 1;
			}
			goto CMP_CA;						//数据接收后比较数量判断接收是否结束
//			return 0;
		}
	}
	else										//非第一次请求
	{
		if( memcmp( &vcn[0], &buf[len], 6 ) == 0 )
		{										//保存
			memcpy( vcn, &buf[len], 6 );		//更新当前的版本，总数，组号

			len += 6;
			bufsize -= 12;
			
			rcode = UP_CAKeyTLV_AnalysisCheckAndSave( &buf[len], bufsize );
			if( rcode != 0 )					//保存参数
			{
				DEF_SysCom_Debug;
				APP_SysErrProc();
				return 1;
			}
			CMP_CA:
			if( memcmp(  &vcn[2], &vcn[4], 2 ) == 0 )
			{									//CA下载完成  根据当前组号与总组号来判断结束否
				rcode = UP_CAKey_DownLoadCAkey_Load();
				if( rcode != 0 )
				{ goto ER; }
				rcode = UP_Write_CAKeyOrICParStat( UP_CAKEY_INDEX, 0 );
				if( rcode != 0 )				//更新状态
				{ goto ER; }
				ver = (( vcn[0] << 8 ) | vcn[1]);
				rcode = UP_Write_Ver( UP_CAKEY_INDEX, ver );
				if( rcode != 0 )				//更新版本号
				{
					ER:
					DEF_SysCom_Debug;
					APP_SysErrProc();
					return 1;
				}
				return 1;
			}
			cout = ( ( vcn[4] << 8 ) | vcn[5] );
			cout++;
			vcn[4] = cout >> 8;
			vcn[5] = cout;
			return 0;
		}
	}
 	return 1;
} 

/*
**************************************************************************************************************
* 
**************************************************************************************************************
*/
U32 AH_Comm_Tx_TcpUP_IC( U08 *buf, U32 *bufsize, U08 *vcn )
{
	U32 len;

	len = 8;
	//========>>数据
	//<1>POS编号
	CurCalc_DataCpy( &buf[len], gSamAppInfo.PsamTID, 6 );
	len +=6;
	//<2>版本号 第一次为终端当前版本号
	memcpy( &buf[len], &vcn[0], 2 );
	len += 2;
	
	//总组数 第一次为0
	memcpy( &buf[len], &vcn[2], 2 );
	len += 2;
	
	//要下发组号 第一次为0
	memcpy( &buf[len], &vcn[4], 2 );
	len += 2;

	ComData_HeadTx( 0x0106, buf, &len );
	*bufsize = len;
 
 	return 0;
}

U32 AH_Comm_Rx_TcpUP_IC( U08 *buf, U32 bufsize, U08 *vcn )
{
	U32 len,rcode,cout,ver;
	U08 rev_buf[400];
	U32 recnum;
					 
	len =0;
	if( bufsize <= 12 )
	{
		DEF_SysCom_Debug; 
		return 1; 
	}
    //<1> POS编号
	if( memcmp( gSamAppInfo.PsamTID, &buf[len], 6 ) != 0 )
	{
		DEF_SysCom_Debug; 
		return 1; 
	}
	len +=6;	
	//<2> 版本号,总组数，当前组号
	
	if( memcmp( &vcn[2], "\x00\x00\x00\x00", 4 ) == 0 )
	{											//第一次请求 总组数，当前组号都为0
		if( memcmp( &vcn[0], &buf[len], 2 ) == 0 )
		{										//第一次请的版本号与响应的版本号一样，有可能不需要下载
			return 1;							//不需要下载
		}
		else									//第一次请的版本号与响应的版本号不一样，进行下载
		{
			if( APP_Get_RecFileNum( DEF_RecMoryBank_Black07, 1, &recnum ) == 0 )
			{												 	//获取未上传的记录
				if(recnum)
				{
					if(APP_Delete_RecFile( DEF_RecMoryBank_Black07, 1, rev_buf, recnum ))//首次下载清空旧记录
					{
						return 1;
					} 	
				}														
			}

			rcode = UP_Write_CAKeyOrICParStat( UP_ICPAR_INDEX, 1 );	//更新状态为未下载
			if( rcode != 0 )					//更新状态
			{ return 1; }

			memcpy( vcn, &buf[len], 6 );		//更新当前的版本，总数，组号
			
//			cout = ( ( vcn[4] << 8 ) | vcn[5] );
//			cout++;
//			vcn[4] = cout >> 8;
//			vcn[5] = cout;
			
			len += 6;
			bufsize -= 12;
			
			rcode = UP_ICParTLV_AnalysisCheckAndSave( &buf[len], bufsize );
			if( rcode != 0 )					//保存参数
			{
				DEF_SysCom_Debug;
				APP_SysErrProc();
				return 1;
			}	
			goto CMP_IC;						//数据接收后比较数量判断接收是否结束	
//			return 0;
		}
	}
	else										//非第一次请求
	{
		if( memcmp( &vcn[0], &buf[len], 6 ) == 0 )
		{										//保存
			memcpy( vcn, &buf[len], 6 );		//更新当前的版本，总数，组号
			len += 6;
			bufsize -= 12;
			
			rcode = UP_ICParTLV_AnalysisCheckAndSave( &buf[len], bufsize );
			if( rcode != 0 )					//保存参数
			{
				DEF_SysCom_Debug;
				APP_SysErrProc();
				return 1;
			}
			CMP_IC:
			if( memcmp(  &vcn[2], &vcn[4], 2 ) == 0 )
			{									//CA下载完成  根据当前组号与总组号来判断结束否
				rcode = UP_CAKey_DownLoadCAkey_Load();
				if( rcode != 0 )				//
				{ goto ER; }
				rcode = UP_Write_CAKeyOrICParStat( UP_ICPAR_INDEX, 0 );
				if( rcode != 0 )				//更新状态
				{ goto ER; }
				ver = (( vcn[0] << 8 ) | vcn[1]);
				rcode = UP_Write_Ver( UP_ICPAR_INDEX, ver );
				if( rcode != 0 )				//更新版本号
				{
					ER:
					DEF_SysCom_Debug;
					APP_SysErrProc();
					return 1;
				}
				return 1;
			}
			cout = ( ( vcn[4] << 8 ) | vcn[5] );
			cout++;
			vcn[4] = cout >> 8;
			vcn[5] = cout;
			return 0;
		}
	}
 	return 1;
} 
/*
**************************************************************************************************************
* 
**************************************************************************************************************
*/
U32 AH_Comm_Tx_TcpUPBin( U08 *buf, U32 *bufsize )
{
	U32 len;

	len = 8;
	//========>>数据
	//<1>POS编号
	CurCalc_DataCpy( &buf[len], gSamAppInfo.PsamTID, 6 );
	len +=6;
	//<2> 版本号
	memcpy( &buf[len], &UPBinInfo.Ver[2], 2 );
	len += 2;
	
	ComData_HeadTx( 0x010B, buf, &len );
	*bufsize = len;
 
 	return 0;
}

U32 AH_Comm_Rx_TcpUPBin( U08 *buf )
{
	U32 len,i;
					 
	len =0;
    //<1> POS编号
	if( memcmp( gSamAppInfo.PsamTID, &buf[len], 6 ) != 0 )
	{ 
		DEF_SysCom_Debug; 
		return 1; 
	}
	len +=6;	
	//<2> 版本号
	memcpy( &UPBinInfo.Ver[2], &buf[len], 2 );
	len +=2;
		
	//<3> 数量
	UPBinInfo.Num = buf[len];
	len += 1;
	if( UPBinInfo.Num > 45 )
	{ UPBinInfo.Num = 45; }
	UPBinInfo.Stat = buf[len];
	len += 1;
	for( i= 0; i < UPBinInfo.Num; i++ )
	{
		memcpy(UPBinInfo.Bin[i],&buf[len],3);	//Bin号
		len += 3;
		UPBinInfo.Bin[i][3] = buf[len];			//卡类别代码
		len += 1;
		memcpy(UPBinInfo.Bin[i]+4,&buf[len],3);	//优惠开始日期 YYMMDD
		len += 3;
		memcpy(UPBinInfo.Bin[i]+7,&buf[len],3);	//优惠结束日期 YYMMDD
		len += 3;
		memcpy(UPBinInfo.Bin[i]+10,&buf[len],2);	//优惠折扣
		len += 2;
	}
	//APP_Save_UPBin( 0 );

 	return 0;
} 


/*
**************************************************************************************************************
*
* 函数原型：U32 Com_Bus_TcpUP_CA( void )
*
* 函数功能：6.6.6	银联认证中心公钥参数下载		 
*
* 函数输入：无
*                
* 函数输出：无
*
* 函数返回：无 
*   
**************************************************************************************************************
*/
U32 Com_Bus_TcpUP_CA( void )
{
	U32 i, rcode,stat,ver;
	U08 vcn[8];

	Hook_Debug_TxData("->公钥下发中...");
	//请求命令
	rcode = UP_Read_Ver( UP_CAKEY_INDEX, &ver );
	if( rcode != 0 )
	{
		DEF_SysCom_Debug;
		APP_SysErrProc();
		return 1;
	}
	
	COM_SerialNum++;	
	stat = 0;
	while( 1 )
	{
		if( stat == 0 ) 							//第一次请求
		{
			stat = 1;
			vcn[0] = ( ver >> 8 ) & 0xFF;
			vcn[1] = ( ver >> 0 ) & 0xFF;			//公钥版本
			vcn[2] = 0x00;
			vcn[3] = 0x00;							//总组数
			vcn[4] = 0x00;
			vcn[5] = 0x00;							//下发组号			
		}

		for( i = 0; i < DEF_SendRecErrMaxNumber; i++ )
		{
			if( AH_Comm_Tx_TcpUP_CA( COM_TxRxBuf, &COM_TxRxBufSize, vcn ) != 0 )
			{ return 1; }		
			//发送命令
			rcode = Com_Dev_TxData( COM_TxRxBuf, COM_TxRxBufSize, ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum );
			if( rcode != 0 )
			{ DEF_SysCom_Debug; return rcode; }
			//接收命令
			rcode = Com_Dev_RxData( COM_TxRxBuf, &COM_TxRxBufSize, sizeof(COM_TxRxBuf), ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum );
			if( rcode != 0 )
			{ DEF_SysCom_Debug; return rcode; }
		
			//==============>>接收数据解析
			rcode = ComData_HeadRx( 0x8105, COM_TxRxBuf, COM_TxRxBufSize );
			if( rcode == 100 )
			{ return rcode; }
			else if( rcode != 0 )
			{ return rcode; }

			//
			rcode = AH_Comm_Rx_TcpUP_CA( &COM_TxRxBuf[8], ( COM_TxRxBufSize - 16 ), vcn );
			if( rcode != 0 )
			{ return rcode; }
			break;
		}
	}
}

/*
**************************************************************************************************************
*
* 函数原型：U32 Com_Bus_TcpUP_IC( void )
*
* 函数功能：6.6.7	银联IC卡参数下载
*
* 函数输入：无
*                
* 函数输出：无
*
* 函数返回：无 
*   
**************************************************************************************************************
*/
U32 Com_Bus_TcpUP_IC( void )
{
	U32 i, rcode,stat,ver;
	U08 vcn[8];

	Hook_Debug_TxData("->IC卡参数下发中...");
	//请求命令
	COM_SerialNum++;
	rcode = UP_Read_Ver( UP_ICPAR_INDEX, &ver );
	if( rcode != 0 )
	{
		DEF_SysCom_Debug;
		APP_SysErrProc();
		return 1;
	}
	
	stat = 0;
	while( 1 )
	{
		if( stat == 0 ) 							//第一次请求
		{
			stat = 1;
			vcn[0] = ( ver >> 8 ) & 0xFF;
			vcn[1] = ( ver >> 0 ) & 0xFF;			//IC卡参数版本
			vcn[2] = 0x00;
			vcn[3] = 0x00;							//总组数
			vcn[4] = 0x00;
			vcn[5] = 0x00;							//下发组号			
		}

		for( i = 0; i < DEF_SendRecErrMaxNumber; i++ )
		{
			if( AH_Comm_Tx_TcpUP_IC( COM_TxRxBuf, &COM_TxRxBufSize, vcn ) != 0 )
			{ return 1; }		
			//发送命令
			rcode = Com_Dev_TxData( COM_TxRxBuf, COM_TxRxBufSize, ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum );
			if( rcode != 0 )
			{ DEF_SysCom_Debug; return rcode; }
			//接收命令
			rcode = Com_Dev_RxData( COM_TxRxBuf, &COM_TxRxBufSize, sizeof(COM_TxRxBuf), ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum );
			if( rcode != 0 )
			{ DEF_SysCom_Debug; return rcode; }
		
			//==============>>接收数据解析
			rcode = ComData_HeadRx( 0x8106, COM_TxRxBuf, COM_TxRxBufSize );
			if( rcode == 100 )
			{ return rcode; }
			else if( rcode != 0 )
			{ return rcode; }

			//线路票价更新处理
			rcode = AH_Comm_Rx_TcpUP_IC( &COM_TxRxBuf[8], ( COM_TxRxBufSize - 16 ), vcn );
			if( rcode != 0 )
			{ return rcode; }
			break;
		}
	}
}

/*
**************************************************************************************************************
*
* 函数原型：U32 Com_Bus_TcpUPBin( void )
*
* 函数功能：6.6.7	下载银行卡bin号
*
* 函数输入：无
*                
* 函数输出：无
*
* 函数返回：无 
*   
**************************************************************************************************************
*/
U32 Com_Bus_TcpUPBin( void )
{
	U32 i, rcode;

	//请求命令
	COM_SerialNum++;

	for( i = 0; i < DEF_SendRecErrMaxNumber; i++ )
	{
		if( AH_Comm_Tx_TcpUPBin( COM_TxRxBuf, &COM_TxRxBufSize ) != 0 )		    //下载银联IC 卡其他参数请求组帧
		{  return 1; }
		
		//发送命令
		rcode = Com_Dev_TxData( COM_TxRxBuf, COM_TxRxBufSize, ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum );
		if( rcode != 0 )
		{ DEF_SysCom_Debug; return rcode; }
		//接收命令
		rcode = Com_Dev_RxData( COM_TxRxBuf, &COM_TxRxBufSize, sizeof(COM_TxRxBuf), ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum );
		if( rcode != 0 )
		{ DEF_SysCom_Debug; return rcode; }
	
		//==============>>接收数据解析
		rcode = ComData_HeadRx( 0x810B, COM_TxRxBuf, COM_TxRxBufSize );
		if( rcode == 100 )
		{ return rcode; }
		else if( rcode != 0 )
		{ return rcode; }

		//银行卡bin号更新处理
		return ( AH_Comm_Rx_TcpUPBin( &COM_TxRxBuf[8] ) );
	}
	return 1;
}

/*
**************************************************************************************************************
*黑名单下载组帧	  (黑名单记录) 1区
**************************************************************************************************************
*/
U32 AH_Comm_Tx_BlackDown( U08 *buf, U32 *bufsize )
{
	U32 len;
	U32 m, rcode;

	len = 8;
	//========>>数据
	//<1>POS编号
	CurCalc_DataCpy( &buf[len], gSamAppInfo.PsamTID, 6 );
	len +=6;
	//黑名单版本号
	rcode = APP_ReadBlacklistVersion(DEF_BlkMoryBank_Black01, &m);
	if (rcode != 0)
	{ DEF_SysCom_Debug; return 1; }
	buf[len++] = (m >> 24) & 0xff;
	buf[len++] = (m >> 16) & 0xff;
	buf[len++] = (m >>  8) & 0xff;
	buf[len++] = (m >>  0) & 0xff;
	//最后一个黑名单卡号
	APP_ReadBlacklistReserve(DEF_BlkMoryBank_Black01, &buf[len]);
	if (rcode != 0)
	{ DEF_SysCom_Debug; return 2; }
	len +=8;
	//黑名单个数
	rcode = APP_ReadBlacklistNumber(DEF_BlkMoryBank_Black01, &m);
	if (rcode != 0)
	{ DEF_SysCom_Debug; return 2; }
	buf[len++] = (m >> 24) & 0xff;
	buf[len++] = (m >> 16) & 0xff;
	buf[len++] = (m >> 8) & 0xff;
	buf[len++] = (m >> 0) & 0xff;

	ComData_HeadTx( 0x0010, buf, &len );
	*bufsize = len;
 
 	return 0;
}

/*
**************************************************************************************************************
*
* 函数原型：U32 Com_Bus_TcpBlackDown( void )
*
* 函数功能：黑名单下载
*			标准公交Tcp通讯应用层处理				 
*
* 函数输入：无
*                
* 函数输出：无
*
* 函数返回：无 
*   
**************************************************************************************************************
*/
U32 Com_Bus_TcpBlackDown( void )
{
	U32 rcode, ver, i, n;
	U08 Blk_buf[ 1024 ];
	U08 *p1, *p2;

	while( 1 )
	{
		COM_SerialNum++;
		//请求命令

		for( i = 0; i < DEF_SendRecErrMaxNumber; i++ )		
		{
			rcode = AH_Comm_Tx_BlackDown( COM_TxRxBuf, &COM_TxRxBufSize );
			if(rcode != 0)						    					
			{ return 1; }	
			
			rcode = Com_Dev_TxData( COM_TxRxBuf, COM_TxRxBufSize, ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum );
			if( rcode != 0 )
			{ DEF_SysCom_Debug; return rcode; }
			rcode = Com_Dev_RxData( COM_TxRxBuf, &COM_TxRxBufSize, sizeof(COM_TxRxBuf), ( SysCfg.NetTxRxTimeOut * 1000 ), DEF_TcpChanNum ); 	
			if( rcode != 0 )
			{ DEF_SysCom_Debug; return rcode; }
	
			//==============>>接收数据解析
			rcode = ComData_HeadRx( 0x8010, COM_TxRxBuf, COM_TxRxBufSize );
			if( rcode == 100 )
			{ 
				if( ((COM_TxRxBuf[16] == 0x00 ) && (COM_TxRxBuf[17] == 0x06))||
				   	((COM_TxRxBuf[16] == 0x00 ) && (COM_TxRxBuf[17] == 0x07)))	   //非法黑名单，清掉黑名单
				{
					APP_CreateBlacklistFile( DEF_BlkMoryBank_Black01 );					
					rcode = APP_UpdateBlacklistVersion( DEF_BlkMoryBank_Black01, 0 );
					if( rcode != 0 )
					{ DEF_SysCom_Debug; return rcode; }
					memset( Blk_buf, 0, 40 );
					APP_UpdateBlacklistReserve( DEF_BlkMoryBank_Black01, Blk_buf );
					if( rcode != 0 )
					{ DEF_SysCom_Debug; return rcode; }
					
					DEF_SysCom_Debug; 
					continue ;
				}
				return rcode; 
			}
			else if( rcode != 0 )
			{ return rcode; }

			//黑名单数量
			n = ((COM_TxRxBuf[14]<<8) | (COM_TxRxBuf[15]<<0));
			if( n == 0 )
			{ return 0; }
			
			//黑名单存储			
			i = 0;
			p1 = &COM_TxRxBuf[16];
			p2 = Blk_buf;
			while( n != 0 )
			{
				*p2++ = *p1++;	  
				*p2++ = *p1++;
				*p2++ = *p1++;
				*p2++ = *p1++;	
				*p2++ = *p1++;	  
				*p2++ = *p1++;
				*p2++ = *p1++;
				*p2++ = *p1++;	
				*p2++ = *p1++;	

				i++;
				n--;
				if((i == 80) || (n == 0)) //这里需要改进一下，这里也需要保存一下最后一个黑名单与版本号??
				{
					rcode = APP_SaveBlacklist(DEF_BlkMoryBank_Black01, 
												Blk_buf, 
												i, 
												NCAP_BlacklistBuffer );
				   	if( rcode != 0 )										//保存黑名单
					{ DEF_SysCom_Debug; return 5; }
					i = 0;
					p2 = Blk_buf;
				}
			}
			//保存最后一个黑名单
			rcode = APP_UpdateBlacklistReserve( DEF_BlkMoryBank_Black01, &COM_TxRxBuf[COM_TxRxBufSize - 20] );
			if( rcode != 0 )												//保存黑名单
			{ DEF_SysCom_Debug; return 5; }
			//更新版本
			ver = (COM_TxRxBuf[COM_TxRxBufSize - 12] << 24) | 	 
	              (COM_TxRxBuf[COM_TxRxBufSize - 11] << 16) | 
			      (COM_TxRxBuf[COM_TxRxBufSize - 10] << 8) | 
				  (COM_TxRxBuf[COM_TxRxBufSize - 9] << 0);
			rcode = APP_UpdateBlacklistVersion( DEF_BlkMoryBank_Black01, ver );
			if(rcode != 0)												
			{ DEF_SysCom_Debug; return 6; }
			break;
		}
		if( i >= DEF_SendRecErrMaxNumber )
		{ return 4; }
	}
}
